<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Title</title>
  </head>
  <body>
    <script>
      Function.prototype.call = function (context) {
        /** 如果第一个参数传入的是 null 或者是 undefined, 那么指向this指向 window/global */
        /** 如果第一个参数传入的不是null或者是undefined, 那么必须是一个对象 */

        if (!context) {
          //context为null或者是undefined
          context = typeof window === "undefined" ? global : window;
        }

        context.fn = this; //this指向的是当前的函数(Function的实例)

        let rest = [...arguments].slice(1); //获取除了this指向对象以外的参数, 空数组slice后返回的仍然是空数组
        let result = context.fn(...rest); //隐式绑定,当前函数的this指向了context.
        delete context.fn;
        return result;
      };

      //实现apply
      Function.prototype.apply = function (context, rest) {
        if (!context) {
          //context为null或者是undefined时,设置默认值
          context = typeof window === "undefined" ? global : window;
        }
        context.fn = this;
        let result;
        if (rest === undefined || rest === null) {
          //undefined 或者 是 null 不是 Iterator 对象，不能被 ...
          result = context.fn(rest);
        } else if (typeof rest === "object") {
          result = context.fn(...rest);
        }
        delete context.fn;
        return result;
      };

      var foo = {
        name: "Selina",
      };
      var name = "Chirs";
      function bar(job, age) {
        console.log(this.name);
        console.log(job, age);
      }
      bar.apply(foo, ["programmer", 20]);
    </script>
  </body>
</html>
